package juc;
/*
结论一：一个对象里面有多个synchronized方法，在某一个时候内，只要一个线程去调用一个synchronized方法
其他的线程只能够等待，换句话说，在一个时刻内，只能有唯一的一个线程去访问这些synchronized方法。

锁的是当前对象this，被锁定后，其他的线程都不能够进入当前对象的其他synchronized方法。

结论2：
加普通方法与同步无关

结论3：
synchronized实现同步的基础，java中的每一个对象都可以作为锁。
具体表现为一下三种形式：
对于普通同步方法。锁的是当前实例对象。
对于同步同步方法块，锁的是synchronized括号里配置的对象
对于静态同步方法，锁的是当前的类的Class对象
 */
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/*
情形一：标准情况下，两个线程分别访问同一个对象的不同方法，输出结果为：
*************sendEmails----
*************sendMes----
2、暂停4秒钟邮件方法，打印结果为？
*************sendEmails----
*************sendMes----
3、新增普通方法sayHello(),请问是先打印邮件还是sayHello
*******sayHello---
*************sendEmails----

4、2部手机，请问是先打印邮件还是短袖
*************sendMes----
*************sendEmails----
5、2个静态同步方法，1部手机，请问是先打印邮件还是短信
*************sendEmails----
*************sendMes----
6、2个静态同步方法，2部手机，请问是先打印邮件还是短信
*************sendEmails----
*************sendMes----
7、1个静态同步方法，1个普通同步方法，1部手机，请问是先打印邮件还是短信
*************sendMes----
*************sendEmails----
8、1个静态同步方法，1个普通同步方法，2部手机，请问是先打印邮件还是短信
*************sendMes----
 *************sendEmails----
 */
public class Test03 {
    public static void main(String[] args) throws InterruptedException {
        phone p = new phone();

        //创建两个线程
        new Thread(() -> {
            try {
                p.sendEmails();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }).start();
        Thread.sleep(100);
        new Thread(() -> {
            try {
                p.sendMSG();
                //p.sayHello();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }).start();
    }
}
class phone {
    //2、暂停4秒钟邮件方法，打印结果为？
    public synchronized void sendEmails() throws InterruptedException {
            TimeUnit.SECONDS.sleep(4);
        System.out.println("*************sendEmails----");
    }
    public synchronized void sendMSG()  throws IOException {
        System.out.println("*************sendMes----");
    }
    public void sayHello()  throws IOException{
        System.out.println("*******sayHello---");
    }
}
